package cn.com.surker.production.entity.vo;

import cn.com.surker.base.ExportInter;
import cn.com.surker.enums.ICodeDescEnum;
import cn.com.surker.enums.production.indent.RoadTypeEnum;
import cn.com.surker.enums.production.invoice.*;
import cn.com.surker.excel.ExcelCell;
import cn.com.surker.production.entity.ProductionInvoice;
import cn.com.surker.util.MathUtils;
import cn.com.surker.util.StringUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * 完整的发货单信息表
 *
 * @author luotao
 * @date 2024/10/11
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class ProductionInvoiceVo extends ProductionInvoice implements ExportInter {

	/**
	 * 合同编号
	 */
	private String conCode;

	/**
	 * 任务单号
	 */
	// @ExcelCell(value = "任务单编号", sort = 1)
	@ExcelCell(value = "任务单编号", sort = 1, childSort = -1)
	private String indentCode;

	/**
	 * 合同名称
	 */
	@ExcelCell(value = "工程名称", sort = 2)
	private String conName;

	/**
	 * 客户名称
	 */
	@ExcelCell(value = "客户名称", sort = 3)
	private String clientName;

	public String getClientName() {
		String cn = this.clientName;
		if (StringUtils.isNotBlank(cn)) {
			cn = cn.replaceAll("\\s+", "");
			cn.toUpperCase();
		}
		return cn;
	}

	/**
	 * 施工单位
	 */
	private String builder;

	public String getBuilder() {
		String bd = this.builder;
		if (StringUtils.isNotBlank(bd)) {
			bd = bd.replaceAll("\\s+", "");
			bd.toUpperCase();
		}
		return bd;
	}

	/**
	 * 销售人员
	 */
	private String sales;

	/**
	 * 强度等级id
	 */
	private Long strengthId;

	/**
	 * 强度等级名
	 */
	// @ExcelCell(value = "砼强度", sort = 6)
	private String strengthName;

	/**
	 * 塌落度
	 */
	private String slumps;

	/**
	 * 特性要求
	 */
	@ExcelCell(value = "特性要求", sort = 7)
	private String tech;

	/**
	 * 前场工长
	 */
	private String foreman;

	/**
	 * 浇筑方式id
	 */
	private Long castModelId;

	/**
	 * 浇筑方式名
	 */
	@ExcelCell(value = "浇筑方式", sort = 5)
	private String castModelName;

	/**
	 * 浇筑方式是否需要付费,0或null,不需要付费;1:需要付费
	 */
	private Integer castModelCost;

	/**
	 * 泵送设备名,
	 */
	@ExcelCell(value = "泵送设备", sort = 9)
	private String pumpDeviceName;

	/**
	 * 泵送类型
	 */
	private Long pumpTypeId;

	/**
	 * 泵送类型名
	 */
	private String pumpTypeName;

	/**
	 * 泵送规格
	 */
	private Long pumpNormId;

	/**
	 * 泵送规格名
	 */
	private String pumpNormName;

	/**
	 * 施工部位
	 */
	@ExcelCell(value = "施工部位", sort = 4)
	private String site;

	/**
	 * 生产方式
	 */
	@ExcelCell(value = "生产方式", sort = 6, childSort = 2)
	private String createTypeTxt;

	public String getCreateTypeTxt() {
		@NotNull(message = "请选择生产方式") Integer proType = this.getCreateType();
		InvoiceCreateTypeEnum anEnum = ICodeDescEnum.getEnum(InvoiceCreateTypeEnum.class, proType);
		if (anEnum != null) {
			return anEnum.getDescription();
		} else {
			return "";
		}
	}

	@ExcelCell(value = "发货类型", sort = 6, childSort = 3)
	private String invoiceTypeTxt;

	public String getInvoiceTypeTxt() {
		InvoiceSendTypeEnum anEnum = ICodeDescEnum.getEnum(InvoiceSendTypeEnum.class, getInvoiceType());
		if (anEnum != null) {
			return anEnum.getDescription();
		} else {
			return null;
		}
	}

	/**
	 * 生产线
	 */
	@ExcelCell(value = "生产线", sort = 27)
	private String mixName;

	/**
	 * 流程状态
	 */
	private String processTxt;

	public String getProcessTxt() {
		InvoiceProcessEnum anEnum = ICodeDescEnum.getEnum(InvoiceProcessEnum.class, getProcess());
		if (anEnum != null) {
			return anEnum.getDescription();
		} else {
			return "";
		}
	}

	/**
	 * 工地地址
	 */
	private String address;

	/**
	 * 工地联系人
	 */
	private String linkMan;

	/**
	 * 工地联系方式
	 */
	private String linkPhone;

	/**
	 * 计划方量
	 */
	private String planStere;

	private String receiptTypeTxt;

	private String specialClearTypeTxt;

	private String calcTranStereTxt;

	private String roadTypeTxt;
	/**
	 * 经度
	 */
	private String lng;
	/**
	 * 纬度
	 */
	private String lat;
	/**
	 * 合同ID
	 */
	private Long conId;

	/**
	 * 统计条数
	 */
	private Integer countTotal;

	public String getReceiptTypeTxt() {
		ReceiptTypeEnum anEnum = ICodeDescEnum.getEnum(ReceiptTypeEnum.class, getReceiptType());
		if (anEnum != null) {
			return anEnum.getDescription();
		} else {
			return "";
		}
	}

	public String getSpecialClearTypeTxt() {
		SpecialClearTypeEnum anEnum = ICodeDescEnum.getEnum(SpecialClearTypeEnum.class, getSpecialClearType());
		if (anEnum != null) {
			return anEnum.getDescription();
		} else {
			return "";
		}
	}


	public String getRoadTypeTxt() {
		RoadTypeEnum anEnum = ICodeDescEnum.getEnum(RoadTypeEnum.class, getRoadType());
		if (anEnum != null) {
			return anEnum.getDescription();
		} else {
			return "";
		}
	}

	public String getCalcTranStereTxt() {
		Integer calcTranStere = getCalcTranStere();
		if (calcTranStere != null && calcTranStere == 1) {
			return "计算";
		} else {
			return "不计算";
		}
	}

	private String isWeightTxt;

	public String getIsWeightTxt() {
		Integer isWeight = getIsWeight();
		if (isWeight != null && isWeight == 0) {
			return "需要";
		} else {
			return "不需要";
		}
	}

	private String isAddTxt;

	public String getIsAddTxt() {
		Integer isAdd = getIsAdd();
		if (isAdd == null || isAdd == 0) {
			return "累计";
		} else {
			return "不累计";
		}
	}

	/**
	 * 施工方退回方量	关联退回单查询
	 */
	@ExcelCell(value = "客户退回方量", sort = 19, calcTotal = true)
	private Double buildReStere;

	/**
	 * 过磅退回方量
	 */
	// @ExcelCell(value = "过磅退回方量", sort = 18, calcTotal = true)
	private Double weightReStere;

	/**
	 * 转出方量	关联操作记录查询
	 */
	@ExcelCell(value = "转出方量", sort = 25)
	private Double outStere;

	/**
	 * 作废方量 关联操作记录查询
	 */
	@ExcelCell(value = "作废方量", sort = 26, calcTotal = true)
	private Double scrapStere;

	/**
	 * 转入方量(表示其他发货单实际生产的方量剩下的转入)
	 * 为累计,如果有多次转入,则显示统计
	 * 改为从关联表查询
	 */
	@ExcelCell(value = "转入方量", sort = 14, childSort = 1)
	private Double inStere;

	/**
	 * 转入备注
	 */
	@ExcelCell(value = "转入备注", sort = 29)
	private String inRemark;

	/**
	 * 累计车次,累计车次以及累计方量采用计算的方式,不写死
	 */

	/*@ExcelCell(value = "累计车次", sort = 12)
	private Integer totalCar;

	public Integer getTotalCar() {
		Integer process = getProcess();
		if (InvoiceProcessEnum.SCRAP.getCode().equals(process)) {
			//	作废的不管
			return null;
		}
		return totalCar;
	}

	*//**
	 * 累计方量
	 *//*
	@ExcelCell(value = "累计方量", sort = 13)
	private Double totalStere;

	public Double getTotalStere() {
		Integer process = getProcess();
		if (InvoiceProcessEnum.SCRAP.getCode().equals(process)) {
			//	作废的不管
			return null;
		}
		totalStere = MathUtils.decimal(totalStere);
		return totalStere;
	}*/

	/**
	 * 发货单真实装载方量,为发货单的生产方量加转入方量
	 */
	// @ExcelCell(value = "装载方量", sort = 14, childSort = 2, calcTotal = true)
	private Double carLoadStere;

	public Double getCarLoadStere() {
		carLoadStere = MathUtils.add(getProStere(), getInStere());
		return carLoadStere;
	}

	/**
	 * 量差方量,为发货方量-真实装载方量 > 0
	 */
	private Double diffStere;

	public Double getDiffStere() {
		diffStere = MathUtils.subtract(getSendStere(), getCarLoadStere());
		return diffStere;
	}

	/**
	 * 审核状态
	 */
	private String examineTxt;
	/**
	 * 小票抬头
	 */
	private String receiptUnit;
	/**
	 * 调度开盘时间
	 */
	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	private Date dispatchStartTime;

	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	private Date endTime;

	/**
	 * 运输策略
	 */
	private Integer strategy;

	/**
	 * 任务单状态
	 */
	private String indentType;
	/**
	 * 生产线名称
	 */
	private String lineName;
	/**
	 * 砂浆方量
	 */
	private Double mortarStere;

	/**
	 * 公司名称
	 */
	private String orgName;
	/**
	 * 驾驶员电话
	 */
	private String phone;
	/**
	 * 公司经度
	 */
	private String orgLng;
	/**
	 * 公司纬度
	 */
	private String orgLat;

	/**
	 * 车自编号
	 * 2025-03-03取消发货单的车辆自编号,该属性由生产合同关联车辆中的属性指定
	 */
	@ExcelCell(value = "运输车辆", sort = 10)
	private String carCode;

	/**
	 * 车牌号
	 * 2025-03-03取消发货单的车牌号,改由通过车辆关联
	 */
	@ExcelCell(value = "运输车辆", sort = 11)
	private String carNo;

	/**
	 * 2025-03-06,从发货单属性移植到签收属性
	 * 签收方量,当签收方量为空的时候,默认使用发货方量
	 * 签收方量不为空的情况下,可以修改;
	 * 如果签收方量不为空,表示已经签收,则不能进行修改作废操作
	 */
	@ExcelCell(value = "工地签收方量", sort = 16, calcTotal = true)
	private Double signStere;

	public Double getSignStere() {
		Integer process = getProcess();
		Integer isAdd = getIsAdd();
		Integer invoiceType = getInvoiceType();
		if (InvoiceProcessEnum.SCRAP.getCode().equals(process) || (isAdd != null && isAdd.equals(1))
			|| (!InvoiceSendTypeEnum.CONCRETE.getCode().equals(invoiceType) && !InvoiceSendTypeEnum.SAND.getCode().equals(invoiceType))) {
			//	作废的,不累计的,不是砼和砂浆的
			return null;
		} else {
			return signStere;
		}
	}
	/**
	 * 生产方量
	 */
	@ExcelCell(value = "生产方量", sort = 14, calcTotal = true)
	private Double proStere;

	/**
	 * 工地实际使用方量,
	 * 计算方式:实际生产方量+转入方量-过磅退回方量
	 * 20250530修改,实际使用量为发货方量-施工方退回方量
	 */
	@ExcelCell(value = "工地实际使用方量", sort = 17, calcTotal = true)
	private Double realUseStere;

	public Double getRealUseStere() {
		Integer process = getProcess();
		if (InvoiceProcessEnum.SCRAP.getCode().equals(process)) {
			//	作废的不管
			return null;
		}
		//	是否累计
		Integer isAdd = getIsAdd();
		if (isAdd != null && isAdd == 1) {
			//	不累计
			return null;
		}
		//	总方量
		// Double totalStere = MathUtils.add(getProStere(), getInStere());
		/*Double carLoadStere = getCarLoadStere();
		Double weightReStere = getWeightReStere();
		if (weightReStere == null || weightReStere.equals(0)) {
			//	减去转出
			realUseStere = MathUtils.subtract(carLoadStere, getOutStere());
		} else {
			//	退回方量
			realUseStere = MathUtils.subtract(carLoadStere, weightReStere);
		}*/
		Double sendStere = getSendStere();
		Double buildReStere = getBuildReStere();
		realUseStere = MathUtils.subtract(sendStere, buildReStere);
		return realUseStere;
	}

	/**
	 * 累计盘方量
	 */
	private Double batchStere;
	/**
	 * 累计盘号
	 */
	private Integer batchNum;
	/**
	 * 退回量差
	 * 计算方式
	 */
	@ExcelCell(value = "退回量差", sort = 17, calcTotal = true)
	private Double reDiffStere;

	/**
	 * 施工方退回已签方量
	 * 计算方式:签收方量-发货量差-实际使用方量
	 */
	// @ExcelCell(value = "退回已签", sort = 22, calcTotal = true)
	private Double buildReSign;

	public Double getBuildReSign() {
		Integer process = getProcess();
		if (InvoiceProcessEnum.SCRAP.getCode().equals(process)) {
			//	作废的不管
			return null;
		}
		Double buildReStere = getBuildReStere();
		if (buildReStere == null) {
			//	如果没有退回方量,则不存在退回未签
			return null;
		}
		//	签收方量
		Double signStere = getSignStere();
		//	发货量差
		// Double sendDiffStere = getSendDiffStere();
		//	实际使用
		Double realUseStere = getRealUseStere();
		// Double a = MathUtils.subtract(signStere, sendDiffStere);
		buildReSign = MathUtils.subtract(signStere, realUseStere);
		return buildReSign;
	}

	/**
	 * 施工方退回未签
	 * 计算方式:退回方量-签收方量
	 */
	// @ExcelCell(value = "退回未签", sort = 23, calcTotal = true)
	private Double buildReNoSign;

	public Double getBuildReNoSign() {
		Integer process = getProcess();
		if (InvoiceProcessEnum.SCRAP.getCode().equals(process)) {
			//	作废的不管
			return null;
		}
		//	施工方退回方量
		Double buildReStere = getBuildReStere();
		if (buildReStere == null) {
			//	如果没有退回方量,则不存在退回未签
			return null;
		}
		Double buildReSign = getBuildReSign();
		buildReNoSign = MathUtils.subtract(buildReStere, buildReSign);
		return buildReNoSign;
	}

	/**
	 * 发货量差,发货量差=发货方量-实际生产量
	 *
	 * @return
	 */
	@ExcelCell(value = "发货量差", sort = 15, childSort = 2, calcTotal = true)
	private Double sendDiffStere;

	public Double getSendDiffStere() {
		Double sendStere = getSendStere();
		/*if (sendStere == null || sendStere.equals(0d)) {
			return 0d;
		}*/
		//	总方量
		Double carLoadStere = getCarLoadStere();
		//
		Double subtract = MathUtils.subtract(sendStere, carLoadStere);
		return subtract;
	}

	/**
	 * 运输或者泵送结算方量,计算方式为小票发货方量-过磅退回方量
	 */
	// @ExcelCell(value = "车队结算方量", sort = 23)
	private Double carBillStere;

	private Double sumSendStere;

	public Double getCarBillStere() {
		carBillStere = MathUtils.subtract(getSendStere(), getWeightReStere());
		return carBillStere;
	}

	@ExcelCell(value = "新老站", sort = 29)
	private String stationName;

	public String getStationName() {
		Long erpId = getErpId();
		if (erpId == null) {
			return "新站";
		} else {
			return "老站";
		}
	}

	/**
	 * 泵送车队
	 */
	@ExcelCell(value = "泵送车队", sort = 9)
	private String pumpTeamCode;

	/**
	 * 用于打印的强度等级
	 */
	@ExcelCell(value = "砼强度", sort = 6)
	private String printStrength;

	public String getPrintStrength() {
		printStrength = getStrengthName();
		Integer invoiceType = getInvoiceType();
		if (InvoiceSendTypeEnum.SAND.getCode().equals(invoiceType)) {
			//	润管砂浆
			printStrength = InvoiceSendTypeEnum.SAND.getDescription();
		} else if (InvoiceSendTypeEnum.WATER_WITHIN.getCode().equals(invoiceType)) {
			//	站内接水
			printStrength = InvoiceSendTypeEnum.WATER_WITHIN.getDescription();
		} else if (InvoiceSendTypeEnum.WATER_WITHOUT.getCode().equals(invoiceType)) {
			//	站外接水
			printStrength = InvoiceSendTypeEnum.WATER_WITHOUT.getDescription();
		} else if (InvoiceSendTypeEnum.UNFINISHED_WATER.getCode().equals(invoiceType)) {
			//	未发水
			printStrength = InvoiceSendTypeEnum.UNFINISHED_WATER.getDescription();
		}
		return printStrength;
	}

	//	获取报表的时候,需要对统计数据的发货方量进行优化
	public Double getSendStere() {
		// 判定是否不累计
		Integer isAdd = getIsAdd();
		if (isAdd != null && isAdd == 1) {
			//	不累计
			return 0d;
		}
		//	发货单类型
		Integer invoiceType = getInvoiceType();
		if (InvoiceSendTypeEnum.CONCRETE.getCode().equals(invoiceType) || InvoiceSendTypeEnum.SAND.getCode().equals(invoiceType)) {
			Double sendStere = super.getSendStere();
			return sendStere;
		} else {
			//	除了水外,返回为空
			return 0d;
		}
	}

	/**
	 * 浇筑方式
	 */
	public Long castModeId;

	/**
	 * 泵送设备
	 */
	public Long pumpDeviceId;

	/**
	 * 是否需要公司派遣设备(0:不需要派遣;1:需要派遣)
	 */
	private Integer castModeCost;
}
